package org.amphiption.gametimer.screen;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.amphiption.gametimer.ApplicationConstants;
import org.amphiption.gametimer.R;
import org.amphiption.gametimer.entity.Player;
import org.amphiption.gametimer.entity.TimerConfiguration;
import org.amphiption.gametimer.entity.TimerConfiguration.TimerType;
import org.amphiption.gametimer.screen.component.ActivePlayerComponent;
import org.amphiption.gametimer.screen.component.PlayerComponent;
import org.amphiption.gametimer.service.ITimerService;
import org.amphiption.gametimer.service.ITimerService.TimerState;
import org.amphiption.gametimer.service.TimerService;
import org.amphiption.gametimer.service.TimerService.TimerServiceListener;
import org.amphiption.gametimer.service.TimerServiceBinder;
import org.amphiption.gametimer.util.GameComponentAngleComparator;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
import android.view.animation.BounceInterpolator;

import com.amphiprion.prototype.GameScreen;
import com.amphiprion.prototype.component.ButtonComponent;
import com.amphiprion.prototype.component.IActionListener;
import com.amphiprion.prototype.component.animation.AlplaComponentAnimation;
import com.amphiprion.prototype.component.animation.ScaleComponentAnimation;
import com.amphiprion.prototype.control.ControlerState;
import com.amphiprion.prototype.util.BitmapUtil;
import com.amphiprion.prototype.util.DrawUtil;
import com.amphiprion.prototype.util.NormalizedBitmap;

public class TimingSessionScreen extends GameScreen {
	private enum ScreenState {
		NONE, TIMER_RUNNING
	}

	private TimerConfiguration timerConfiguration;
	private ITimerService service;

	private ScreenState screenState = ScreenState.NONE;
	private NormalizedBitmap background;
	private List<PlayerComponent> playerComponents;
	private int currentPlayerIndex = -1;
	private ActivePlayerComponent currentPlayerNameCmp;

	public TimingSessionScreen(final Context context, TimerConfiguration tc, PlayerComponent[] originalPlayerComponents, PlayerComponent firstPlayer) {
		super(context);
		this.timerConfiguration = tc;

		playerComponents = new ArrayList<PlayerComponent>();

		for (int i = 0; i < originalPlayerComponents.length; i++) {
			final PlayerComponent pc = new PlayerComponent(tc.getPlayers().get(i), 0, 0, tc.getTimerType() == TimerType.TURN_COUNTER);
			playerComponents.add(pc);
			if (originalPlayerComponents[i] == firstPlayer) {
				firstPlayer = pc;
			}
			pc.setX(originalPlayerComponents[i].getX());
			pc.setY(originalPlayerComponents[i].getY());
			pc.setRotation(originalPlayerComponents[i].getRotation());

			float angle = DrawUtil.getAngle(new PointF(pc.getX(), pc.getY()), new PointF(getReferenceWidth() / 2, getReferenceHeight() / 2));
			if (angle < 0) {
				angle = 360 + angle;
			}

			addComponent(pc);
		}
		Collections.sort(playerComponents, new GameComponentAngleComparator(getReferenceWidth() / 2, getReferenceHeight() / 2));

		for (Player p : tc.getPlayers()) {
			if (tc.getTimerType() == TimerType.GAME_TIMER) {
				if (!tc.isHandicap()) {
					p.setCounter(tc.getDuration() * 1000);
				} else {
					p.setCounter(p.getDuration() * 1000);
				}
			} else if (tc.getTimerType() == TimerType.SHARED_GAME_TIMER) {
				p.setCounter(tc.getDuration() * 1000);
			} else {
				p.setCounter(0);
			}
		}

		final int firstPlayerIndex = playerComponents.indexOf(firstPlayer);

		final Intent intent = new Intent(context, TimerService.class);
		intent.putExtra("TIMER_CONFIGURATION", tc);

		final TimerServiceListener listener = new TimerServiceListener() {

			@Override
			public void updateUi(int counter) {

				if (currentPlayerIndex != -1) {
					if (timerConfiguration.getTimerType() == TimerType.SHARED_GAME_TIMER) {
						for (PlayerComponent pc : playerComponents) {
							pc.getPlayer().setCounter(counter);
						}
					} else {
						playerComponents.get(currentPlayerIndex).getPlayer().setCounter(counter);
					}
				}
			}

			@Override
			public void stateChanged() {
				if (screenState == ScreenState.NONE) {
					gotoSwitchPlayer(firstPlayerIndex);
				}
				// Log.d(ApplicationConstants.PACKAGE, "stateChanged");
			}

			@Override
			public void resumed() {
				// TODO Auto-generated method stub

			}

			@Override
			public void paused() {
				// TODO Auto-generated method stub

			}

			@Override
			public void warn() {
				try {
					if (TimingSessionScreen.this.timerConfiguration.getOwnTuneWarning() == null) {
						MediaPlayer mp = MediaPlayer.create(context, R.raw.beep);
						mp.start();
					} else {
						MediaPlayer mp = MediaPlayer.create(context, Uri.parse(TimingSessionScreen.this.timerConfiguration.getOwnTuneWarning()));
						mp.start();
					}
				} catch (Throwable e) {
					Log.e(ApplicationConstants.PACKAGE, "", e);
				}
			}

			@Override
			public void endReached() {
				try {
					// Uri alert =
					// RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
					// Log.d(ApplicationConstants.PACKAGE, "" + alert);
					if (TimingSessionScreen.this.timerConfiguration.getOwnTune() == null) {
						MediaPlayer mp = MediaPlayer.create(context, R.raw.tone);
						mp.start();
					} else {
						MediaPlayer mp = MediaPlayer.create(context, Uri.parse(TimingSessionScreen.this.timerConfiguration.getOwnTune()));
						mp.start();
					}
					// MediaPlayer mMediaPlayer = new MediaPlayer();
					// mMediaPlayer.setDataSource(getContext(), alert);
					// final AudioManager audioManager = (AudioManager)
					// getContext().getSystemService(Context.AUDIO_SERVICE);
					// if
					// (audioManager.getStreamVolume(AudioManager.STREAM_ALARM)
					// != 0) {
					// mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
					// // player.setLooping(true);
					// mMediaPlayer.prepare();
					// mMediaPlayer.start();
					// }
				} catch (Throwable e) {
					Log.e(ApplicationConstants.PACKAGE, "", e);
				}
			}
		};

		ServiceConnection connection = new ServiceConnection() {
			@Override
			public void onServiceConnected(ComponentName name, IBinder binder) {
				service = ((TimerServiceBinder) binder).getService();
				service.setTimerServiceListener(listener);
				if (service.getState() == TimerState.INIT) {
					context.startService(intent);
				}

			}

			@Override
			public void onServiceDisconnected(ComponentName name) {
			}
		};

		context.bindService(intent, connection, Context.BIND_AUTO_CREATE);

	}

	private void gotoSwitchPlayer(int playerIndex) {

		if (screenState == ScreenState.NONE) {
			for (int i = 0; i < playerComponents.size(); i++) {
				final int index = i;
				final PlayerComponent pc = playerComponents.get(i);
				pc.setActionListener(new IActionListener() {
					@Override
					public void actionPerformed(Object source) {
						if (screenState == ScreenState.TIMER_RUNNING && currentPlayerIndex != index) {
							gotoSwitchPlayer(index);
						}
					}
				});
			}
			final ButtonComponent left = new ButtonComponent("left.png", getReferenceWidth() / 2 - 100, getReferenceHeight() / 2 - 220, 255);
			left.setActionListener(new IActionListener() {
				@Override
				public void actionPerformed(Object source) {
					left.addAnimation(new ScaleComponentAnimation(800, 0, 0.75f, 1.0f, new BounceInterpolator()));
					if (screenState == ScreenState.TIMER_RUNNING) {
						if (currentPlayerIndex > 0) {
							gotoSwitchPlayer(currentPlayerIndex - 1);
						} else {
							gotoSwitchPlayer(playerComponents.size() - 1);
						}
					}
				}
			});
			addComponent(left);

			final ButtonComponent right = new ButtonComponent("right.png", getReferenceWidth() / 2 + 100, getReferenceHeight() / 2 - 220, 255);
			right.setActionListener(new IActionListener() {
				@Override
				public void actionPerformed(Object source) {
					if (screenState == ScreenState.TIMER_RUNNING) {
						right.addAnimation(new ScaleComponentAnimation(800, 0, 0.75f, 1.0f, new BounceInterpolator()));
						if (currentPlayerIndex < playerComponents.size() - 1) {
							gotoSwitchPlayer(currentPlayerIndex + 1);
						} else {
							gotoSwitchPlayer(0);
						}
					}
				}
			});
			addComponent(right);

			final ButtonComponent btPause = new ButtonComponent("pause.png", getReferenceWidth() / 2, getReferenceHeight() / 2 + 150, 255);
			final ButtonComponent btPlay = new ButtonComponent("play.png", getReferenceWidth() / 2, getReferenceHeight() / 2 + 150, 0);
			btPause.setActionListener(new IActionListener() {
				@Override
				public void actionPerformed(Object source) {
					if (screenState == ScreenState.TIMER_RUNNING) {

						service.pause();
						btPause.setAlpha(0);
						btPlay.setAlpha(255);
						btPlay.addAnimation(new ScaleComponentAnimation(800, 0, 0.75f, 1.0f, new BounceInterpolator()));
					}
				}
			});
			addComponent(btPause);

			btPlay.setActionListener(new IActionListener() {
				@Override
				public void actionPerformed(Object source) {
					if (screenState == ScreenState.TIMER_RUNNING) {
						service.pause();
						btPause.setAlpha(255);
						btPlay.setAlpha(0);
						btPause.addAnimation(new ScaleComponentAnimation(800, 0, 0.75f, 1.0f, new BounceInterpolator()));
					}
				}
			});
			addComponent(btPlay);
			// currentPlayerNameCmp = new TextComponent("", 40.0f, Color.WHITE,
			// getReferenceWidth() / 2, getReferenceHeight() / 2 - 150, 255);
			currentPlayerNameCmp = new ActivePlayerComponent(playerComponents.get(playerIndex).getPlayer(), getReferenceWidth() / 2, getReferenceHeight() / 2, 250, 350, 255, timerConfiguration.getTimerType() == TimerType.TURN_COUNTER);
			addComponent(currentPlayerNameCmp);
		}
		if (currentPlayerIndex != -1) {
			playerComponents.get(currentPlayerIndex).clearAnimations();
			playerComponents.get(currentPlayerIndex).setAlpha(255);
		}
		currentPlayerIndex = playerIndex;
		playerComponents.get(currentPlayerIndex).addAnimation(new AlplaComponentAnimation(750, 0, 255, 50, true, true));
		playerComponents.get(currentPlayerIndex).addAnimation(new ScaleComponentAnimation(800, 0, 0.75f, 1.0f, new BounceInterpolator()));

		currentPlayerNameCmp.setPlayer(playerComponents.get(currentPlayerIndex).getPlayer());

		service.startPlayer(currentPlayerIndex);
		screenState = ScreenState.TIMER_RUNNING;

	}

	@Override
	public void onInput(ControlerState state, long elpased) {
		super.onInput(state, elpased);
	}

	@Override
	protected float getReferenceWidth() {
		return 480;
	}

	@Override
	protected float getReferenceHeight() {
		return 800;
	}

	@Override
	protected boolean isLandscape() {
		return false;
	}

	@Override
	protected void onPreDraw(Canvas canvas) {
		if (background != null) {
			drawImage(canvas, background.bitmap, getReferenceWidth() / 2, getReferenceHeight() / 2, 1.0f);
		}
	}

	@Override
	protected void onPostDraw(Canvas canvas) {

	}

	@Override
	public void activate() {
		background = BitmapUtil.loadBitmap("table.png");
		super.activate();
	}

	@Override
	public void desactivate() {
		BitmapUtil.unloadBitmap("table.png");
		super.desactivate();
	}

	@Override
	public boolean onBackRequested() {
		service.stop();
		// getContext().stopService(intentService);
		view.removeScreen(1);
		return true;
	}
}
